// import com.alibaba.druid.DbType;
// import com.alibaba.druid.sql.ast.SQLCommentHint;
// import com.alibaba.druid.sql.ast.SQLHint;
// import com.alibaba.druid.sql.ast.statement.SQLErrorLoggingClause;
// import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
// import com.alibaba.druid.sql.dialect.oracle.ast.clause.OracleReturningClause;
// import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.util.ArrayList;
// import java.util.List;

#include "OracleInsertStatement.h"
#include "../../../../../DbType.h"
#include "../../../../ast/SQLCommentHint.h"
#include "../../../../ast/SQLHint.h"
#include "../../../../ast/statement/SQLErrorLoggingClause.h"
#include "../../../../ast/statement/SQLExprTableSource.h"
#include "../../../../ast/statement/SQLSelect.h"
#include "../clause/OracleReturningClause.h"
#include "../../visitor/OracleASTVisitor.h"
#include "../../../../visitor/SQLASTVisitor.h"
#include "../../../../../utils/listTran.h"

OracleInsertStatement::OracleInsertStatement()
{
  dbType = DbType_ptr(new DbType(&DbType::oracle));
  hints = std::make_shared<std::list<SQLHint_ptr>>();
}

void OracleInsertStatement::cloneTo(OracleInsertStatement_ptr x)
{
  SQLInsertStatement::cloneTo(x);
  if (returning != nullptr)
  {
    x->setReturning(std::dynamic_pointer_cast<OracleReturningClause>(returning->clone()));
  }
  if (errorLogging != nullptr)
  {
    x->setErrorLogging(std::dynamic_pointer_cast<SQLErrorLoggingClause>(errorLogging->clone()));
  }
  for (SQLHint_ptr hint : *hints)
  {
    SQLHint_ptr h2 = std::dynamic_pointer_cast<SQLHint>(hint->clone());
    h2->setParent(x);
    x->hints->push_back(h2);
  }
}

SQLHint_list_ptr OracleInsertStatement::getHints()
{
  return hints;
}

void OracleInsertStatement::setHints(SQLHint_list_ptr hints)
{
  this->hints = hints;
}

OracleReturningClause_ptr OracleInsertStatement::getReturning()
{
  return returning;
}

void OracleInsertStatement::setReturning(OracleReturningClause_ptr returning)
{
  this->returning = returning;
}

SQLErrorLoggingClause_ptr OracleInsertStatement::getErrorLogging()
{
  return errorLogging;
}

void OracleInsertStatement::setErrorLogging(SQLErrorLoggingClause_ptr errorLogging)
{
  this->errorLogging = errorLogging;
}

// @Override
void OracleInsertStatement::accept0(SQLASTVisitor_ptr visitor)
{
  this->accept0(std::dynamic_pointer_cast<OracleASTVisitor>(visitor));
}

void OracleInsertStatement::accept0(OracleASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(OracleInsertStatement)))
  {
    this->acceptChild(visitor, getTableSource());
    SQLObject_list_ptr tmp1 = ListTran::tran_class<SQLExpr, SQLObject>(getColumns());
    this->acceptChild(visitor, tmp1);
    this->acceptChild(visitor, getValues());
    this->acceptChild(visitor, getQuery());
    this->acceptChild(visitor, returning);
    this->acceptChild(visitor, errorLogging);
  }

  visitor->endVisit(SharedObject(OracleInsertStatement));
}

SQLObject_ptr OracleInsertStatement::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<OracleInsertStatement>(new OracleInsertStatement());
  std::shared_ptr<OracleInsertStatement> x = std::dynamic_pointer_cast<OracleInsertStatement>(clone_tmp);
  // OracleInsertStatement x = new OracleInsertStatement();
  cloneTo(x);
  return x;
}

// @Override
SQLCommentHint_list_ptr OracleInsertStatement::getHeadHintsDirect()
{
  return nullptr;
}
